package org.dylan.web.tag.script;

import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dylan.core.util.ClassLoaderUtil;

/**
 * 解析定义的script脚本路径信息
 * 
 * @author dylan
 * 
 */
public class ScriptDefineParser {
	private static Map<String, ScriptModel> scriptMap = Collections
			.synchronizedMap(new HashMap<String, ScriptModel>());
	private static Log logger = LogFactory.getLog(ScriptDefineParser.class);

	static {
		parseScriptDefine(ClassLoaderUtil.getResourceAsStream(
				"script-define.xml", ScriptDefineParser.class));
		parseScriptDefine(ClassLoaderUtil.getResourceAsStream(
				"/script-define.xml", ScriptDefineParser.class));
	}

	/**
	 * 从资源路径中解析脚本的定义信息
	 * 
	 * @param is
	 */
	private static void parseScriptDefine(InputStream is) {
		SAXReader saxReader = new SAXReader();
		Document document;
		try {
			document = saxReader.read(is);
		} catch (DocumentException e) {
			logger.warn("error during parse script define.", e);
			// ignored.
			return;
		}
		List list = document.selectNodes("/script-define/script");
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Element element = (Element) iter.next();
			ScriptModel model = parseScriptElement(element);
			if (model != null) {
				scriptMap.put(model.getId(), model);
			}
		}
	}

	private static ScriptModel parseScriptElement(Element element) {
		ScriptModel model = new ScriptModel();
		Element eleId = element.element("id");
		if (eleId == null) {
			logger.warn("script without 'id' element,ignored.");
			return null;
		}
		String id = eleId.getTextTrim();
		if (StringUtils.isBlank(id)) {
			logger.warn("script without 'id' defined,ignored.");
			return null;
		}
		Element elePath = element.element("path");
		Element eleDebugPath = element.element("debugPath");
		if (elePath == null && eleDebugPath == null) {
			logger.warn("script of '" + id
					+ "' without 'path' and 'debugPath' element,ignored.");
			return null;
		}
		String path = elePath == null ? null : elePath.getTextTrim();
		String debugPath = eleDebugPath == null ? null : eleDebugPath
				.getTextTrim();
		if (StringUtils.isBlank(path) && StringUtils.isBlank(debugPath)) {
			logger.warn("script of '" + id
					+ "' without 'path' and 'debugPath' defined,ignored.");
			return null;
		}
		model.setId(id);
		if (StringUtils.isBlank(path)) {// no path defined.
			model.setPath(debugPath);
			model.setDebugPath(debugPath);
		} else if (StringUtils.isBlank(debugPath)) {// no debugPath defined.
			model.setPath(path);
			model.setDebugPath(path);
		} else {
			model.setPath(path);
			model.setDebugPath(debugPath);
		}
		return model;
	}

	/**
	 * 返回解析到的script集合
	 * 
	 * @return
	 */
	public static Map<String, ScriptModel> scripts() {
		return scriptMap;
	}

}
